package com.mlnx.bluwifi.manager;

import com.alibaba.fastjson.JSONObject;
import com.mlnx.bluwifi.pojo.DataCache;
import com.mlnx.bluwifi.pojo.dto.ConnectParam;
import com.mlnx.bluwifi.service.WifiBluService;
import com.mlnx.bluwifi.utils.HttpUtil;
import com.mlnx.bluwifi.utils.SpolanyaUtils;
import com.mlnx.common.utils.MyLog;
import com.mlnx.device.entity.Device;
import com.mlnx.device.entity.LanyaDevice;
import com.mlnx.device.service.LanyaDeviceService;
import org.shan.spring.rest.RestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by amanda.shan on 2019/11/18.
 */
@Component
@Order(1)
public class ConDeviceManage {

    private static ConDeviceManage instance = null;

    private Object syn = new Object();

    public static ConDeviceManage getInstance() {
        return instance;
    }

    private MyLog log = MyLog.getLog(this.getClass());

    private Map<String, Boolean> connectAp = new ConcurrentHashMap<>();

    private Set<String> connectedSpo = new HashSet<>();

    private Map<String, AtomicBoolean> deviceConnectingAp = new ConcurrentHashMap<>();

    private Map<String, AtomicBoolean> apConnectingAp = new ConcurrentHashMap<>();

    @Autowired
    private LanyaDeviceService lanyaDeviceService;

    @Autowired
    private WifiBluService wifiBluService;

    @PostConstruct
    public void init() {
        instance = this;
        new AskSpoOnlineTask(lanyaDeviceService, wifiBluService).start();

        List<LanyaDevice> list = lanyaDeviceService.list();
        for (LanyaDevice lanyaDevice : list) {
            if(lanyaDevice.getStartUsing()==0){
                SpoDataTask spoDataTask = new SpoDataTask(lanyaDevice.getMac(), lanyaDevice.getIpAddress(), wifiBluService);
                spoDataTask.start();
            }
        }

    }

    public void setApStatus(String mac, boolean connected) {
        connectAp.put(mac, connected);
    }

    public Set<String> getConnectedSpo() {
        return connectedSpo;
    }

    public void connect(String deviceMac, String blueMac, String ip, String type) {

        if (judgeExist(deviceMac)) {
//            log.debug("{}蓝牙设备已经连接", deviceMac);
            return;
        }

        AtomicBoolean deviceConenctState = null;
        AtomicBoolean apConenctState = null;

        synchronized (syn) {
            deviceConenctState = deviceConnectingAp.get(deviceMac);
            if (deviceConenctState == null) {
                deviceConenctState = new AtomicBoolean(false);
                deviceConnectingAp.put(deviceMac, deviceConenctState);
            }

            apConenctState = apConnectingAp.get(blueMac);
            if (apConenctState == null) {
                apConenctState = new AtomicBoolean(false);
                apConnectingAp.put(blueMac, apConenctState);
            }
        }

        // 连接蓝牙设备
        ConnectParam connectParam = new ConnectParam();
        connectParam.setType(type);

        // ap 正在工作
        if (!apConenctState.compareAndSet(false, true)) {
            return;
        }

        log.debug("ap: {} 的连接的蓝牙设备:{} 状态:{}", blueMac, deviceMac, deviceConenctState);
        // 正在连接该设备
        if (!deviceConenctState.compareAndSet(false, true)) {
            // 将ap设置成空闲
            apConenctState.set(false);
            return;
        }

        try {
            log.info("ap:{} 开始连接蓝牙设备:{}", blueMac, deviceMac);

            String result = RestUtils.post(SpolanyaUtils.getConnectUrl(deviceMac, ip), String.class,
                    JSONObject.toJSONString(connectParam));
            log.info("{}连接蓝牙设备result:{}", deviceMac, result);
            if ("OK".equals(result)) {
                // 使能读取设备数据
                Device device = wifiBluService.getDevice(deviceMac);
                switch (device.getDeviceTypeId()){
                    case XIAOLOU_SPO_DEVICE:
                        inputCmd(deviceMac);
                        result = HttpUtil.sendGet(SpolanyaUtils.getXiaolouInputCmdUrl(deviceMac, ip),
                                "?mac=" + blueMac + "&access_token=");
                        break;
                    case ECG_DEVICE:
                        inputCmd(deviceMac);
                        result = HttpUtil.sendGet(SpolanyaUtils.getEcgInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
                                "&access_token=");
                        break;
                    case YOUR_BP:
                        inputCmd(deviceMac);
                        result = HttpUtil.sendGet(SpolanyaUtils.getYouRBPInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
                                "&access_token=");
                        break;
                    case ZK_BP:
                        inputCmd(deviceMac);
                        result = HttpUtil.sendGet(SpolanyaUtils.getInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
                                "&access_token=");
                        break;
                    case SPO_DEVICE:
                        inputCmd(deviceMac);
                        result = HttpUtil.sendGet(SpolanyaUtils.getInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
                                "&access_token=");
                        break;
                    default:
                        break;
                }
                log.info("{}使能接收蓝牙设备数据result:{}", deviceMac, result);
//                if (DeviceType.XIAOLOU_SPO_DEVICE.equals(device.getDeviceTypeId())) {
//                    inputCmd(deviceMac);
//                    result = HttpUtil.sendGet(SpolanyaUtils.getXiaolouInputCmdUrl(deviceMac, ip),
//                            "?mac=" + blueMac + "&access_token=");
//                }else if(DeviceType.ECG_DEVICE.equals(device.getDeviceTypeId())){
//                    inputCmd(deviceMac);
//                    result = HttpUtil.sendGet(SpolanyaUtils.getEcgInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
//                            "&access_token=");
//                }else if(DeviceType.YOUR_BP.equals(device.getDeviceTypeId())){
//                    inputCmd(deviceMac);
//                    result = HttpUtil.sendGet(SpolanyaUtils.getYouRBPInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
//                            "&access_token=");
//                }else {
//                    inputCmd(deviceMac);
//                    result = HttpUtil.sendGet(SpolanyaUtils.getInputCmdUrl(deviceMac, ip), "?mac=" + blueMac +
//                            "&access_token=");
//                }
//                log.info("{}使能接收蓝牙设备数据result:{}", deviceMac, result);

                if ("OK".equals(result)) {
                    connectedSpo.add(deviceMac);
                } else {
                    log.error("{}使能接收蓝牙设备数据失败", deviceMac);
                }

            } else {
                log.error("{}连接蓝牙设备失败:", deviceMac);
            }
        } catch (Exception e) {
            log.error(e, "发送  请求出现异常{" + connectParam.toString() + "}+url={" + SpolanyaUtils.getConnectUrl(deviceMac,
                    ip) + "}+");
        } finally {
            deviceConenctState.set(false);
            apConenctState.set(false);
        }

    }

    public void setConnectedSpo(Set<String> connectedSpo) {
        this.connectedSpo = connectedSpo;
    }

    private boolean judgeExist(String deviceMac) {
        return connectedSpo.contains(deviceMac);
    }

    private void inputCmd(String deviceMac) {
        DataCache dataCache=SpoPolicy.getInstance().getDataCache(deviceMac);
        dataCache.setCurrentTime(System.currentTimeMillis());
        SpoPolicy.getInstance().setDataCache(dataCache,deviceMac);
        log.info("更新设备{} 时间{}", deviceMac, dataCache.getCurrentTime());


    }

    public static void main(String[] args) {

        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        System.out.println(atomicBoolean.compareAndSet(false, true));
        System.out.println(atomicBoolean.compareAndSet(false, true));
    }

}
